
#include <iostream>
#include <string>
#include <memory>

// 实现接口 (Implementor) - 定义视频格式接口
class VideoFormat {
public:
    virtual ~VideoFormat() = default;
    virtual void decode(const std::string& fileName) = 0;
};

// 具体实现类 (Concrete Implementor) - MP4 格式
class MP4Format : public VideoFormat {
public:
    void decode(const std::string& fileName) override {
        std::cout << "Decoding MP4 format: " << fileName << std::endl;
    }
};

// 具体实现类 (Concrete Implementor) - AVI 格式
class AVIFormat : public VideoFormat {
public:
    void decode(const std::string& fileName) override {
        std::cout << "Decoding AVI format: " << fileName << std::endl;
    }
};

// 抽象类 (Abstraction) - 定义播放器接口
class VideoPlayer {
public:
    virtual ~VideoPlayer() = default;

    // 设置实现部分的接口对象
    void setFormat(std::shared_ptr<VideoFormat> format) {
        this->format = format;
    }

    // 播放视频方法，抽象类只定义接口，具体实现由扩展抽象类提供
    virtual void play(const std::string& fileName) = 0;

protected:
    std::shared_ptr<VideoFormat> format;  // 实现部分的引用
};

// 扩展抽象类 (Refined Abstraction) - 基础播放器
class BasicPlayer : public VideoPlayer {
public:
    void play(const std::string& fileName) override {
        std::cout << "Playing video in Basic Player: ";
        format->decode(fileName);
    }
};

// 扩展抽象类 (Refined Abstraction) - 高级播放器
class AdvancedPlayer : public VideoPlayer {
public:
    void play(const std::string& fileName) override {
        std::cout << "Playing video in Advanced Player: ";
        format->decode(fileName);
    }
};

// 客户端代码
int main() {
    // 创建 MP4 和 AVI 格式对象
    std::shared_ptr<VideoFormat> mp4 = std::make_shared<MP4Format>();
    std::shared_ptr<VideoFormat> avi = std::make_shared<AVIFormat>();

    // 创建播放器对象
    std::unique_ptr<VideoPlayer> basicPlayer = std::make_unique<BasicPlayer>();
    std::unique_ptr<VideoPlayer> advancedPlayer = std::make_unique<AdvancedPlayer>();

    // 使用 BasicPlayer 播放 MP4 格式
    basicPlayer->setFormat(mp4);
    basicPlayer->play("video1.mp4");

    // 使用 AdvancedPlayer 播放 AVI 格式
    advancedPlayer->setFormat(avi);
    advancedPlayer->play("video2.avi");

    return 0;
}


